Return description and author for installed packages#1165
Return description and author for installed packages#1165bricestacey wants to merge 2 commits intomainfrom
Conversation
Extend .ps.rpc.pkg_list to return `description` and `author` alongside the existing fields so Positron's Packages pane card view can render them. Both are normalized for display: descriptions collapse whitespace so multi-line text fits on one line, and author strips trailing `<email>` markers from Maintainer values. All three methods (pak / base / renv) populate the new fields. base and renv share a helper that wraps utils::installed.packages() so the lib lookup only differs by `lib.loc`. See posit-dev/positron#12925
There was a problem hiding this comment.
Some high-level thoughts:
- It's not immediately obvious to me why a pak variant is needed when listing installed packages and perhaps enriching with some information from DESCRIPTION. My instinct is that someone choosing or accepting a pak lifestyle re: packages pane operations is really (and probably only?) about installation. I suspect this can be simplified to using something like
.ps.pkg_list_installed()for pak/base/renv and just feeding thelib.locin the renv case. - I'd lean more into R's native vectorization. I think there's a lot of explicit iteration that can be eliminated. I gather some sort of row-by-row move is needed eventually to get this into the needed shape, but I think we can do that all at once at the last moment. Something along these lines:
.ps.pkg_list_installed <- function(lib.loc = NULL) {
ip <- utils::installed.packages(
lib.loc = lib.loc,
fields = c("Description", "Maintainer")
)
pkgs <- ip[, "Package"]
vers <- ip[, "Version"]
description <- trimws(gsub(
"\\s+",
" ",
ifelse(is.na(ip[, "Description"]), "", ip[, "Description"]),
perl = TRUE
))
maintainer <- trimws(gsub(
"\\s*<[^>]+>",
"",
gsub(
"\\s+",
" ",
ifelse(is.na(ip[, "Maintainer"]), "", ip[, "Maintainer"]),
perl = TRUE
),
perl = TRUE
))
ids <- paste0(pkgs, "-", vers)
Map(
function(id, pkg, ver, description, maintainer) {
list(
id = id,
name = pkg,
displayName = pkg,
version = ver,
description = description,
maintainer = maintainer
)
},
ids,
pkgs,
vers,
description,
maintainer
)
}
|
Here's a slightly cleaner version of my suggestion: .ps.pkg_list_installed <- function(lib.loc = NULL) {
ip <- utils::installed.packages(
lib.loc = lib.loc,
fields = c("Description", "Maintainer")
)
name <- ip[, "Package"]
version <- ip[, "Version"]
id <- paste0(name, "-", version)
description <- trimws(gsub(
"\\s+",
" ",
ifelse(is.na(ip[, "Description"]), "", ip[, "Description"]),
perl = TRUE
))
maintainer <- trimws(gsub(
"\\s*<[^>]+>",
"",
gsub(
"\\s+",
" ",
ifelse(is.na(ip[, "Maintainer"]), "", ip[, "Maintainer"]),
perl = TRUE
),
perl = TRUE
))
Map(
list,
id = id,
name = name,
displayName = name,
version = version,
description = description,
maintainer = maintainer
)
}The |
Address review feedback: collapse pak/base/renv into a single .ps.pkg_list_installed() that always uses utils::installed.packages(), scoped by lib.loc for the renv method. The pak::lib_status() branch went away since pak's value is in install/update, not listing. Replace the per-row lapply with vectorized whitespace/email scrubbing and a single Map() to assemble the per-package lists.
5b45b2d to
cd9f03e
Compare
We have https://packaging.pypa.io/en/stable/utils.html#packaging.utils.canonicalize_name |
Extend .ps.rpc.pkg_list to return
descriptionandauthoralongside the existing fields so Positron's Packages pane card view can render them. Both are normalized for display: descriptions collapse whitespace so multi-line text fits on one line, and author strips trailing<email>markers from Maintainer values.All three methods (pak / base / renv) populate the new fields. base and renv share a helper that wraps utils::installed.packages() so the lib lookup only differs by
lib.loc.See posit-dev/positron#12925